
package com.bear.cmcc.NetTestHTTP.service;

import com.bear.cmcc.NetTestHTTP.R;
import com.bear.cmcc.NetTestHTTP.component.NetTestLogBean;
import com.bear.cmcc.NetTestHTTP.component.NetTestTimesInfoBean;
import com.bear.cmcc.NetTestHTTP.component.ServersConfigBean;
import com.bear.cmcc.NetTestHTTP.constant.FtpConstant;
import com.bear.cmcc.NetTestHTTP.constant.MyCommonConstant;
import com.bear.cmcc.NetTestHTTP.db.NetTestDBControl;
import com.bear.cmcc.NetTestHTTP.util.FtpUtil;
import com.bear.cmcc.NetTestHTTP.util.MyCommonUtil;
import com.bear.cmcc.NetTestHTTP.util.NetTestUtil;

import org.apache.commons.net.ftp.FTPClient;

import android.content.Context;
import android.util.Log;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;
import java.util.ArrayList;

public class NetUpLoadThread /* extends Thread */{

    private static final String TAG = "NetUpLoadThread";

    private static final String FILENAME = "512K.txt";

    private Context context;

    private int countTestNum;

    private long roundTimes = 0;

    private int fileFQsize;// 下载时缓存分区大小

    private NetTestTimesInfoBean netTestTimesInfoBean;

    private int roundID;// round表最后一个pid（关联times表的roundID），times表的最后一个pid+1（关联cell表的timesID）

    private String netType = null;

    private ServersConfigBean serverConfigBean;

    public double oneTimesAverageSpeed, oneTempSpeed, roundMaxSpeed, roundMinSpeed, maxSpeed,
            minSpeed, oneLogAveragespeed, roundAverageSpeed, roundFileSize;// 一次测试的平均速度、临时速度变量、最大速度、最小速度,保存一次log的平均速度

    private boolean timesFirstContrastSpeed;// 表示每次测试时是否是第一次对比速度，用来过滤掉第一次不保存maxspeed、minspeed

    public boolean success;

    private boolean isInterrupted = false;

    public boolean isInterrupted() {
        return isInterrupted;
    }

    public void setInterrupted(boolean isInterrupted) {
        this.isInterrupted = isInterrupted;
    }

    public NetUpLoadThread(Context context, int num) {
        this.context = context;
        this.countTestNum = num;
    }

    public int getRoundID() {
        return roundID;
    }

    public void setRoundID(int roundID) {
        this.roundID = roundID;
    }

    public String getNetType() {
        return netType;
    }

    public void setNetType(String netType) {
        this.netType = netType;
    }

    public double getRoundAverageSpeed() {
        return roundAverageSpeed;
    }

    // @Override
    public void run() {
        try {
            NetTestDBControl dbControl = new NetTestDBControl(context);
            serverConfigBean = NetTestUtil.getServerBean(context);// 获取要测试的服务器配置信息
           
            for (int i = 0; i < countTestNum && (!isInterrupted); i++) {
                initialLogParameter(context);
                upLoadAllFileToFjFTP(context);
                if (netTestTimesInfoBean.getNetType() == null) {
                    netTestTimesInfoBean.setNetType(netType);
                }
                dbControl.insertToUpTestTimesInfo(netTestTimesInfoBean);
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                NetTestUtil.setOneTimesFinishBroad(context, i + 1, success);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*
     * 初始化、fileFQsize、netTestTimesInfoBean对象
     */
    private void initialLogParameter(Context context) {
        timesFirstContrastSpeed = false;
        oneTimesAverageSpeed = 0.0;
        fileFQsize = NetTestUtil.getNetworkInfo(context, new NetTestLogBean());

        netTestTimesInfoBean = new NetTestTimesInfoBean();
        netTestTimesInfoBean.setRoundID(roundID);
    }

    public boolean upLoadAllFileToFjFTP(Context context) {
        boolean success = false;
        if (context == null) {
            return false;
        }
        FTPClient ftp = null;
        try {
            if (MyCommonUtil.isNetworkAviable(context)) {
                // netLogBeanInitial(context);
               
                ftp = FtpUtil.ftpInitial(FtpConstant.ComFtpFjConfig.hostFJ, null,
                        FtpConstant.ComFtpFjConfig.userUploadFJ,
                        FtpConstant.ComFtpFjConfig.passUploadFJ);
                File file = saveAssetsToFile(context, FILENAME);
                long beginTime = System.currentTimeMillis();
                testUpload(context, ftp, file, System.currentTimeMillis());
                long endTime = System.currentTimeMillis();
                roundTimes = roundTimes + (endTime - beginTime);
            }
        } catch (Exception e) {
            Log.d(TAG, " upLoadAllFileByComFTP -->Exception: " + e.getMessage());
        } finally {
            FtpUtil.ftpDestroy(ftp);
        }
        return success;

    }

    /**
     * 拷贝assets目录下的某个文件到 /data/data/<package name>/files/FTP/FJ/ 目录下
     * 
     * @param context
     * @param srcAsset
     * @return
     */
    private File saveAssetsToFile(Context context, String srcAsset) {
        InputStream inStream = null;
        FileOutputStream fs = null;
        File file = null;
        try {
            String imdiMd5 = MyCommonUtil.getDeviceByMD5(MyCommonUtil.getDeviceId(context));
            int byteread = 0;
            inStream = context.getAssets().open(srcAsset);
            file = new File(context.getFilesDir() + "/" + imdiMd5);
            if (!file.exists()) {
                fs = new FileOutputStream(file);
                byte[] buffer = new byte[1024];
                while ((byteread = inStream.read(buffer)) != -1) {
                    fs.write(buffer, 0, byteread);
                }
                inStream.close();
                fs.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            try {
                if (inStream != null)
                    inStream.close();
                if (fs != null)
                    fs.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return file;
    }

    /*
     * 测试下载，获取参数
     */
    private void testUpload(Context context, FTPClient ftpClient, File file, long timeBegin) {
        long roundSpeedts = 0;
        int reply = -1;
        // boolean success = false;
        FileOutputStream fos = null;
        // BufferedOutputStream outStream = null;
        OutputStream outStream = null;
        InputStream inputStream = null;
        BufferedInputStream buff = null;
        // long remoteFileSize = 0;// 文件大小
        ArrayList<Double> fancai = new ArrayList<Double>();
        try {

            inputStream = new FileInputStream(file);
            int allsum = 0;
            int count = 0;

            while (count == 0) {
                count = inputStream.available();
            }
            // netLogBean = new NetTestLogBean();

            // long allstartTime = System.currentTimeMillis();// 总的开启时间
            long onestartTime = System.currentTimeMillis();// 用来对比log
            long speedonestartTime = System.currentTimeMillis();// 用来对比速率
            boolean isInterrupted = false;
            int onesize = 0;
            int oneSpeedSize = 0;
            if (inputStream != null) {
                byte[] b = new byte[fileFQsize];
                int j = 0;
                double temp = 0;
                maxSpeed = 0;
                minSpeed = 0;

                outStream = ftpClient.storeFileStream(file.getName() + "-"
                        + MyCommonUtil.getCurDateHasMinute() + ".zip");

                if (outStream != null) {
                    while ((!isInterrupted && (j = inputStream.read(b, 0, fileFQsize)) != -1)) {

                        long oneendTime = System.currentTimeMillis();
                        long speedoneendTime = System.currentTimeMillis();
                        long ts = oneendTime - onestartTime;
                        long speedts = speedoneendTime - speedonestartTime;
                        roundSpeedts = roundTimes + (oneendTime - timeBegin);
                        onesize += j;
                        oneSpeedSize += j;
                        roundFileSize += j;
                        outStream.write(b, 0, j);
                        allsum = allsum + j;

                        if (speedts >= 200)// 每200ms对比一次speed //修改时时刷新！
                        {
                            // 获取轮平均速度
                            temp = (double) ((double) roundFileSize / roundSpeedts / 1024 * 1000 * MyCommonConstant.NetTestConstant.addMultiple);
                            if (temp > 0) {
                                roundAverageSpeed = temp;// 过滤零值
                            }

                            oneTempSpeed = (double) ((double) oneSpeedSize / speedts / 1024 * 1000 * MyCommonConstant.NetTestConstant.addMultiple);
                            if (!timesFirstContrastSpeed) {
                                if (maxSpeed == 0)
                                    maxSpeed = oneTempSpeed;
                                if (minSpeed == 0)
                                    minSpeed = oneTempSpeed;
                                if (roundMaxSpeed == 0)
                                    roundMaxSpeed = oneTempSpeed;
                                if (roundMinSpeed == 0)
                                    roundMinSpeed = oneTempSpeed;

                                maxSpeed = (maxSpeed < oneTempSpeed) ? oneTempSpeed : maxSpeed;
                                minSpeed = (minSpeed > oneTempSpeed) ? oneTempSpeed : minSpeed;
                                roundMaxSpeed = (roundMaxSpeed < oneTempSpeed) ? oneTempSpeed
                                        : roundMaxSpeed;
                                roundMinSpeed = (roundMinSpeed > oneTempSpeed) ? oneTempSpeed
                                        : roundMinSpeed;
                            }
                            // timesFirstContrastSpeed = false;
                            speedonestartTime = speedoneendTime;
                            oneSpeedSize = 0;
                            // 发送广播到前台提示当前速度
                            String ftpForward = context.getString(R.string.ftp_up);
                            Log.i("linyz", "NetUpLoadThread发送广播到前台提示当前速度" + ftpForward);
                            NetTestUtil.sendNetTestSpeedBroad(roundAverageSpeed, roundMaxSpeed,
                                    roundMinSpeed, ftpForward, context);
                            // if (ts >= 1000)// 每秒统计一次log
                            // {
                            oneTimesAverageSpeed = (double) ((double) onesize / ts / 1024 * 1000 * MyCommonConstant.NetTestConstant.addMultiple);
                            fancai.add(oneTimesAverageSpeed);
                            // }
                            Log.i("linyz", "NetUpLoadThread" + ftpForward);
                        }

                    }
                }
                if (outStream != null) {
                    outStream.flush();
                } else {
                    Log.i(TAG, "outStream is null");
                }
            }
            long allendTime = System.currentTimeMillis();

            reply = ftpClient.getReplyCode();

            NetTestLogBean netLogBean = new NetTestLogBean();
            NetTestUtil.getNetworkInfo(context, netLogBean);
            netTestTimesInfoBean.setNetType(netLogBean.getNetType());
            if (netTestTimesInfoBean.getNetType() == null) {
                netTestTimesInfoBean.setNetType(netType);
            }
            netTestTimesInfoBean.setDownServer(serverConfigBean.getServerName());

            if (reply == 150) {
                success = true;
                long ts = allendTime - timeBegin;
                Log.i(TAG, "reply == 226");
                long fl = count;

                double temp1 = (double) ((double) roundFileSize / roundSpeedts / 1024 * 1000 * MyCommonConstant.NetTestConstant.addMultiple);
                if (temp1 > 0) {
                    roundAverageSpeed = temp1;// 过滤零值
                }
                // Log.i("scj", "time f1= "+fl+" count= "+count);
                // Log.i("scj", "time ts= "+ts);
                // Log.i("scj", "roundFileSize = "+roundFileSize);
                Log.i("scj", "up temp1 = " + temp1 + "   roundFileSize=" + roundFileSize
                        + " roundSpeedts " + roundSpeedts);

                netTestTimesInfoBean.setFileSize(String.valueOf(count));
                netTestTimesInfoBean
                        .setAverageSpeed(((double) fl / ts / 1024 * 1000 * MyCommonConstant.NetTestConstant.addMultiple));
                netTestTimesInfoBean.setMaxSpeed(maxSpeed);
                netTestTimesInfoBean.setMinSpeed(minSpeed);
                netTestTimesInfoBean.setWaveShakeStrong(MyCommonUtil.getVarianceTwo(fancai));

            } else {
                success = false;
                Log.d(TAG, TAG + "=>Download fail. Reply Code: " + reply+"----"+ftpClient.getReplyString());
            }
            if (fancai != null) {
                fancai.clear();
            }
        } catch (SocketException e) {
            Log.i(TAG, "SocketException=>" + e.getMessage());
        } catch (IOException e) {
            Log.i(TAG, "IOException=>" + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            Log.i(TAG, "Exception=>" + e.getMessage());
        } finally {
            try {
                if (fos != null) {
                    fos.close();
                }
                if (outStream != null) {
                    outStream.close();
                }
                if (inputStream != null) {
                    inputStream.close();
                }
                if (buff != null) {
                    buff.close();
                }
            } catch (IOException e) {
                Log.d(TAG, "testDownload finally close IOException: " + e.getMessage());
            }
        }
        success = true;
    }
}
